package com.alibaba.citrus.cr.order.open.api.facade.service.calculate;

import com.alibaba.citrus.cr.common.util.TimeUtil;
import com.alibaba.citrus.cr.order.open.api.facade.common.model.WmsOutBoundMessage;
import com.alibaba.citrus.cr.order.open.api.facade.model.CalculateQuantityDTO;
import com.alibaba.citrus.cr.order.open.api.facade.model.TransferOrder;
import com.alibaba.citrus.cr.order.open.api.facade.model.TransferSubOrder;
import com.alibaba.citrus.cr.unified.inventory.contants.FeaturesKey;
import com.alibaba.citrus.cr.unified.inventory.utils.DateUtils;
import com.alibaba.cloud.retail.wms.api.model.orders.common.WarehousingOrderDTO;
import com.alibaba.cloud.retail.wms.api.model.orders.common.WarehousingSubOrderDTO;
import com.alibaba.cz.base.tool.DateFormatUtil;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.feature.Features;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.model.AllocateApplyOrderDetail;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.model.AllocateOrderDetail;
import com.epoch.app.crunifiedinventory.model.enums.FulfillmentTypeEnum;
import com.epoch.app.mninventorycenter.model.dto.SubFeaturesRequest;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * @author yifei
 * @since 2024/1/19
 */
public class CalculateCommonUtil {
    private static Log log = Log.getLogger(CalculateCommonUtil.class);
    // 计划调拨类型
    public static final String PLAN_TRANSFER_TYPE = "1";
    // 仓间调拨类型
    public static final String WAREHOUSE_TRANSFER_TYPE = "5";
    // 货场提货类型
    public static final String FREIGHT_TRANSFER_TYPE = "6";
    // 调拨入、出
    public static final List<Integer> mainOrderTypeList = Lists.newArrayList(12, 22);
    // 调拨出
    public static final Integer ALLOCATE_OUT = 12;
    // 调拨入
    public static final Integer ALLOCATE_IN = 22;
    // 入库
    public static final Integer IN = 1;
    // 出库
    public static final Integer OUT = 2;
    // 累计待出库数量
    public static final String CUMULATIVE_WAIT_OUT_BOUND_QUANTITY = "cumulativeWaitOutboundQuantity";
    // 累计已出库数量
    public static final String CUMULATIVE_DELIVERY_QUANTITY = "cumulativeDeliveryQuantity";
    // 累计已收货数量
    public static final String CUMULATIVE_RECEIVED_QUANTITY = "cumulativeReceivedQuantity";
    // 累计待收货数量
    public static final String CUMULATIVE_WAIT_RECEIVED_QUANTITY = "cumulativeWaitReceivedQuantity";
    // 累计已提货数量
    public static final String CUMULATIVE_PICK_UP_QUANTITY = "cumulativePickUpQuantity";
    // 累计已完成数量
    public static final String CUMULATIVE_COMPLETE_QUANTITY = "cumulativeCompleteQuantity";
    // 出入库单的数量在调拨单上使用时，需要缩小1000倍
    public static final BigDecimal decimal = new BigDecimal(1000);

    public static boolean accept(String message) {
        if (message == null) {
            return false;
        }
        WmsOutBoundMessage wmsOutBoundMessage = JSON.parseObject(message, WmsOutBoundMessage.class);
        log.info("CalculateCommonUtil_accept_message:{}", JSON.toJSONString(wmsOutBoundMessage));
        if (wmsOutBoundMessage.getWmsOrderDTO() == null) {
            return false;
        }
        return mainOrderTypeList.contains(wmsOutBoundMessage.getWmsOrderDTO().getMainOrderType());
    }

    public static CalculateQuantityDTO buildCalculateQuantityDTO(List<WarehousingOrderDTO> warehousingOrderList) {
        // 根据消息体内容判断当前调拨单是出库还是入库，做区分
        // key:业务单据行号，value:明细对应数量的累加
        CalculateQuantityDTO dto = new CalculateQuantityDTO();
        Map<String, BigDecimal> transferWaitOutMap = new HashMap<>();
        Map<String, BigDecimal> transferWaitInMap = new HashMap<>();
        Map<String, BigDecimal> transferConfirmOutMap = new HashMap<>();
        Map<String, BigDecimal> transferConfirmInMap = new HashMap<>();
        Map<String,String> shipTimeMap = Maps.newHashMap();
        Map<String,String> receiveTimeMap = Maps.newHashMap();
        Map<String,String> outBoundProductDateMap = Maps.newHashMap();
        for (WarehousingOrderDTO order : warehousingOrderList) {
            List<com.alibaba.cloud.retail.wms.api.model.orders.common.WmsOrderDetailDTO> wmsOrderDetailList = order.getWmsOrderDetailList();
            if (CollectionUtils.isNotEmpty(wmsOrderDetailList)) {
                // 计算累计待出库数量
                if (ALLOCATE_OUT.equals(order.getMainOrderType())) {
                    calculateQuantity(wmsOrderDetailList, transferWaitOutMap);
                } else if/*计算累计待收货数量*/ (ALLOCATE_IN.equals(order.getMainOrderType())) {
                    calculateQuantity(wmsOrderDetailList, transferWaitInMap);
                }
            }
            List<com.alibaba.cloud.retail.wms.api.model.orders.common.WarehousingSubOrderDTO> orderDetailList = order.getWmsSubOrders();
            if (CollectionUtils.isNotEmpty(orderDetailList)) {
                if (order.getMainOrderType() != null) {
                    // 计算累计已出库
                    if (ALLOCATE_OUT.equals(order.getMainOrderType())) {
                        calculateConfirmQuantity(orderDetailList, transferConfirmOutMap);
                    } else if/*计算累计已收货数量*/ (ALLOCATE_IN.equals(order.getMainOrderType())) {
                        calculateConfirmQuantity(orderDetailList, transferConfirmInMap);
                    }
                } else {
                    if (OUT.equals(orderDetailList.get(0).getMainOrderType())) {
                        calculateConfirmQuantity(orderDetailList, transferConfirmOutMap);
                    } else if (IN.equals(orderDetailList.get(0).getMainOrderType())) {
                        calculateConfirmQuantity(orderDetailList, transferConfirmInMap);
                    }
                }
            }
        }
        /**
         * 写入发货时间,收货时间,出库生产日期
         * 分成出库和入库
         * 找到最后一张出库 和最后一张入库
         */
        computeOutInBoundTime(warehousingOrderList,shipTimeMap,receiveTimeMap,outBoundProductDateMap);

        dto.setTransferWaitOutMap(transferWaitOutMap);
        dto.setTransferWaitInMap(transferWaitInMap);
        dto.setTransferConfirmOutMap(transferConfirmOutMap);
        dto.setTransferConfirmInMap(transferConfirmInMap);

        dto.setShipTimeMap(shipTimeMap);
        dto.setReceiveTimeMap(receiveTimeMap);
        dto.setOutBoundProductDateMap(outBoundProductDateMap);
        return dto;
    }

    public static void calculateQuantity(List<com.alibaba.cloud.retail.wms.api.model.orders.common.WmsOrderDetailDTO> orderDetailList, Map<String, BigDecimal> allocateMap) {
        orderDetailList.forEach(subDetail -> {
            Long goodsQuantity = subDetail.getGoodsQuantity();
            String bizSubOrderId = subDetail.getBizSubOrderId();
            BigDecimal quantity = goodsQuantity == null ? new BigDecimal("0") : new BigDecimal(goodsQuantity);
            // 删除状态子单
            if (subDetail.getStatus() != null && subDetail.getStatus() == -1) {
                quantity = new BigDecimal("0");
            }
            BigDecimal decimal = allocateMap.get(bizSubOrderId);
            if (allocateMap.containsKey(bizSubOrderId)) {
                quantity = quantity.add(decimal);
            }
            allocateMap.put(bizSubOrderId, quantity);
        });
    }

    public static void calculateConfirmQuantity(List<com.alibaba.cloud.retail.wms.api.model.orders.common.WarehousingSubOrderDTO> orderDetailList, Map<String, BigDecimal> allocateMap) {
        orderDetailList.forEach(subDetail -> {
            Long goodsQuantity = subDetail.getGoodsQuantity();
            String bizSubOrderId = subDetail.getBizSubOrderId();
            BigDecimal quantity = goodsQuantity == null ? new BigDecimal("0") : new BigDecimal(goodsQuantity);
            BigDecimal decimal = allocateMap.get(bizSubOrderId);
            if (allocateMap.containsKey(bizSubOrderId)) {
                quantity = quantity.add(decimal);
            }
            allocateMap.put(bizSubOrderId, quantity);
        });
    }

    public static Map<String, SubFeaturesRequest> buildCurrentUpdateMap(TransferOrder orderInfo, Integer wmsOrderType, CalculateQuantityDTO calculateQuantityDTO) {
        Map<String, SubFeaturesRequest> currentFeatures = new HashMap<>();
        for (TransferSubOrder subOrder : orderInfo.getDetailList()) {
            SubFeaturesRequest request = new SubFeaturesRequest();
            Map<String, String> subBizFeaturesToUpdate = new HashMap<>(4);
            if (ALLOCATE_OUT.equals(wmsOrderType)) {
                // 累计待出库数量
                BigDecimal waitOutBoundQty = calculateQuantityDTO.getTransferWaitOutMap().get(subOrder.getLineNo());
                // 累计已出库数量
                BigDecimal confirmOutQty = calculateQuantityDTO.getTransferConfirmOutMap().get(subOrder.getLineNo());
                // 外仓发货不能计算待发货数量
                if (FulfillmentTypeEnum.CURRENT2PILOT.getValue().toString().equals(orderInfo.getFulfillmentTypeCode()) ||
                        FulfillmentTypeEnum.CURRENT2CURRENT.getValue().toString().equals(orderInfo.getFulfillmentTypeCode()) ||
                        FulfillmentTypeEnum.VIRTUAL_TRANSFER.getValue().toString().equals(orderInfo.getFulfillmentTypeCode())) {
                    subBizFeaturesToUpdate.put(CUMULATIVE_WAIT_OUT_BOUND_QUANTITY, convertToString(new BigDecimal("0")));
                } else {
                    subBizFeaturesToUpdate.put(CUMULATIVE_WAIT_OUT_BOUND_QUANTITY, convertToString(subtractBigDecimal(waitOutBoundQty, confirmOutQty)));
                }
                subBizFeaturesToUpdate.put(CUMULATIVE_DELIVERY_QUANTITY, convertToString(confirmOutQty));
            } else if (ALLOCATE_IN.equals(wmsOrderType)) {
                // 累计待收货数量
                BigDecimal waitInBoundQty = calculateQuantityDTO.getTransferWaitInMap().get(subOrder.getLineNo());
                // 累计已收货数量
                BigDecimal confirmInQty = calculateQuantityDTO.getTransferConfirmInMap().get(subOrder.getLineNo());
                // 大仓发货不能计算待收货数量
                if (FulfillmentTypeEnum.PILOT2CURRENT.getValue().toString().equals(orderInfo.getFulfillmentTypeCode()) ||
                        FulfillmentTypeEnum.CURRENT2CURRENT.getValue().toString().equals(orderInfo.getFulfillmentTypeCode()) ||
                        FulfillmentTypeEnum.VIRTUAL_TRANSFER.getValue().toString().equals(orderInfo.getFulfillmentTypeCode())) {
                    subBizFeaturesToUpdate.put(CUMULATIVE_WAIT_RECEIVED_QUANTITY, convertToString(new BigDecimal("0")));
                } else {
                    subBizFeaturesToUpdate.put(CUMULATIVE_WAIT_RECEIVED_QUANTITY, convertToString(subtractBigDecimal(waitInBoundQty, confirmInQty)));
                }
                subBizFeaturesToUpdate.put(CUMULATIVE_RECEIVED_QUANTITY, convertToString(confirmInQty));
            }
            //收发货时间, 出库生产日期
            subBizFeaturesToUpdate.put(FeaturesKey.SHIP_TIME,calculateQuantityDTO.getShipTimeMap().get(subOrder.getLineNo()));
            subBizFeaturesToUpdate.put(FeaturesKey.RECEIVE_TIME,calculateQuantityDTO.getReceiveTimeMap().get(subOrder.getLineNo()));
            subBizFeaturesToUpdate.put(FeaturesKey.OUT_BOUND_PRODUCT_DATE,calculateQuantityDTO.getOutBoundProductDateMap().get(subOrder.getLineNo()));
            request.setSubBizFeaturesToUpdate(subBizFeaturesToUpdate);
            currentFeatures.put(subOrder.getLineNo(), request);
        }
        return currentFeatures;
    }

    public static Map<String, SubFeaturesRequest> buildRelatedTransferUpdateMap(List<AllocateOrderDetail> allocateOrderDetailList) {
        Map<String, SubFeaturesRequest> relatedFeatures = new HashMap<>();
        for (AllocateOrderDetail subOrder : allocateOrderDetailList) {
            String relatedAllocateSubOrderId = subOrder.getRelatedAllocateSubOrderId();
            if (StringUtils.isBlank(relatedAllocateSubOrderId)) {
                continue;
            }
            Features features = Features.newFeatures(subOrder.getBizFeatures());
            // 当前子单上的累计已出库数量
            String deliveryQuantity = features.get(CUMULATIVE_DELIVERY_QUANTITY);
            // 当前子单上的累计已收货数量
            String receivedQuantity = features.get(CUMULATIVE_RECEIVED_QUANTITY);
            if (relatedFeatures.containsKey(relatedAllocateSubOrderId)) {
                SubFeaturesRequest request = relatedFeatures.get(relatedAllocateSubOrderId);
                // 需要计算的累计已出库数量
                cumulativeQuantity(request, CUMULATIVE_PICK_UP_QUANTITY, deliveryQuantity);
                // 累计子单上的累计已收货数量
                cumulativeQuantity(request, CUMULATIVE_COMPLETE_QUANTITY, receivedQuantity);
            } else {
                SubFeaturesRequest request = new SubFeaturesRequest();
                Map<String, String> subBizFeaturesToUpdate = new HashMap<>();
                subBizFeaturesToUpdate.put(CUMULATIVE_PICK_UP_QUANTITY, deliveryQuantity);
                subBizFeaturesToUpdate.put(CUMULATIVE_COMPLETE_QUANTITY, receivedQuantity);
                request.setSubBizFeaturesToUpdate(subBizFeaturesToUpdate);
                relatedFeatures.put(relatedAllocateSubOrderId, request);
            }
        }
        return relatedFeatures;
    }

    public static void cumulativeQuantity(SubFeaturesRequest request, String key, String quantity) {
        String cumulativeQuantity = request.getSubBizFeaturesToUpdate().get(key);
        cumulativeQuantity = cumulativeQuantity(cumulativeQuantity, quantity);
        request.getSubBizFeaturesToUpdate().put(key, cumulativeQuantity);
    }

    public static List<SubFeaturesRequest> buildApplyTransferUpdateList(List<AllocateOrderDetail> transferOrderDetailList, List<AllocateApplyOrderDetail> applyOrderDetailList, String transferType) {
        List<SubFeaturesRequest> subList = new ArrayList<>();
        // 当前调拨单对应预报单地累计待出库数量
        Map<String, BigDecimal> applyTransferWaitOutMap = new HashMap<>();
        // 当前调拨单对应预报单地累计待入库数量
        Map<String, BigDecimal> applyTransferWaitInMap = new HashMap<>();
        // 当前调拨单对应预报单地累计已出库数量
        Map<String, BigDecimal> applyTransferConfirmOutMap = new HashMap<>();
        // 当前调拨单对应预报单地累计已发货数量
        Map<String, BigDecimal> applyTransferConfirmInMap = new HashMap<>();
        // 当前调拨单对应预报单地累计已提货数量
        Map<String, BigDecimal> applyTransferPickUpMap = new HashMap<>();
        // 当前调拨单对应预报单地累计已完成数量
        Map<String, BigDecimal> applyTransferCompleteMap = new HashMap<>();
        for (AllocateOrderDetail detail : transferOrderDetailList) {
            String applyOrderLineId = detail.getAllocateApplyOrderLineId();
            if (StringUtils.isBlank(applyOrderLineId)) {
                continue;
            }
            Features features = Features.newFeatures(detail.getBizFeatures());
            // 当前调拨单子单上地累计待出库数量
            BigDecimal waitOutBoundQty = convertBigDecimal(features.get(CUMULATIVE_WAIT_OUT_BOUND_QUANTITY));
            // 当前调拨单子单上地累计已出库数量
            BigDecimal confirmOutQty = convertBigDecimal(features.get(CUMULATIVE_DELIVERY_QUANTITY));
            // 当前调拨单子单上地累计待收货数量
            BigDecimal waitInBoundQty = convertBigDecimal(features.get(CUMULATIVE_WAIT_RECEIVED_QUANTITY));
            // 当前调拨单子单上地累计已收货数量
            BigDecimal confirmInQty = convertBigDecimal(features.get(CUMULATIVE_RECEIVED_QUANTITY));
            if (applyTransferWaitOutMap.containsKey(applyOrderLineId)) {
                waitOutBoundQty = waitOutBoundQty.add(applyTransferWaitOutMap.get(applyOrderLineId));
            }
            if (applyTransferConfirmOutMap.containsKey(applyOrderLineId)) {
                confirmOutQty = confirmOutQty.add(applyTransferConfirmOutMap.get(applyOrderLineId));
            }
            if (applyTransferWaitInMap.containsKey(applyOrderLineId)) {
                waitInBoundQty = waitInBoundQty.add(applyTransferWaitInMap.get(applyOrderLineId));
            }
            if (applyTransferConfirmInMap.containsKey(applyOrderLineId)) {
                confirmInQty = confirmInQty.add(applyTransferConfirmInMap.get(applyOrderLineId));
            }
            applyTransferWaitOutMap.put(applyOrderLineId, waitOutBoundQty);
            applyTransferConfirmOutMap.put(applyOrderLineId, confirmOutQty);
            applyTransferWaitInMap.put(applyOrderLineId, waitInBoundQty);
            applyTransferConfirmInMap.put(applyOrderLineId, confirmInQty);
            // 货场仓需要额外计算累计已提货和累计已完成数量
            if (FREIGHT_TRANSFER_TYPE.equals(transferType)) {
                // 当前调拨单子单上地累计已提货数量
                BigDecimal pickUpQty = convertBigDecimal(features.get(CUMULATIVE_PICK_UP_QUANTITY));
                // 当前调拨单子单上地累计已完成数量
                BigDecimal completeQty = convertBigDecimal(features.get(CUMULATIVE_COMPLETE_QUANTITY));
                if (applyTransferPickUpMap.containsKey(applyOrderLineId)) {
                    pickUpQty = pickUpQty.add(applyTransferPickUpMap.get(applyOrderLineId));
                }
                if (applyTransferCompleteMap.containsKey(applyOrderLineId)) {
                    completeQty = completeQty.add(applyTransferCompleteMap.get(applyOrderLineId));
                }
                applyTransferPickUpMap.put(applyOrderLineId, pickUpQty);
                applyTransferCompleteMap.put(applyOrderLineId, completeQty);
            }
        }
        log.info("CalculateCommonUtil_buildApplyTransferUpdateList_waitOut:{}|confirmOut:{}|waitIn:{}|confirmIn:{}|pickUp:{}|complete:{}",
                JSON.toJSONString(applyTransferWaitOutMap), JSON.toJSONString(applyTransferConfirmOutMap), JSON.toJSONString(applyTransferWaitInMap),
                JSON.toJSONString(applyTransferConfirmInMap), JSON.toJSONString(applyTransferPickUpMap), JSON.toJSONString(applyTransferCompleteMap));
        for (AllocateApplyOrderDetail applyDetail : applyOrderDetailList) {
            SubFeaturesRequest sub = new SubFeaturesRequest();
            String lineNo = String.valueOf(applyDetail.getLineNo());
            sub.setBizSubOrderLineNo(lineNo);
            Map<String, String> subBizFeaturesToUpdate = new HashMap<>(6);
            if (applyTransferWaitOutMap.containsKey(lineNo)) {
                convertApplyTransferMap(subBizFeaturesToUpdate, CUMULATIVE_WAIT_OUT_BOUND_QUANTITY, applyTransferWaitOutMap,lineNo);
            }
            if (applyTransferConfirmOutMap.containsKey(lineNo)) {
                convertApplyTransferMap(subBizFeaturesToUpdate, CUMULATIVE_DELIVERY_QUANTITY, applyTransferConfirmOutMap,lineNo);
            }
            if (applyTransferWaitInMap.containsKey(lineNo)) {
                convertApplyTransferMap(subBizFeaturesToUpdate, CUMULATIVE_WAIT_RECEIVED_QUANTITY, applyTransferWaitInMap,lineNo);
            }
            if (applyTransferConfirmInMap.containsKey(lineNo)) {
                convertApplyTransferMap(subBizFeaturesToUpdate, CUMULATIVE_RECEIVED_QUANTITY, applyTransferConfirmInMap,lineNo);
            }
            if (FREIGHT_TRANSFER_TYPE.equals(transferType)) {
                if (applyTransferPickUpMap.containsKey(lineNo)) {
                    convertApplyTransferMap(subBizFeaturesToUpdate, CUMULATIVE_PICK_UP_QUANTITY, applyTransferPickUpMap,lineNo);
                }
                if (applyTransferCompleteMap.containsKey(lineNo)) {
                    convertApplyTransferMap(subBizFeaturesToUpdate, CUMULATIVE_COMPLETE_QUANTITY, applyTransferCompleteMap,lineNo);
                }
            }
            sub.setSubBizFeaturesToUpdate(subBizFeaturesToUpdate);
            subList.add(sub);
        }
        return subList;
    }

    public static String cumulativeQuantity(String original, String target) {
        if (original == null) {
            original = "0";
        }
        if (target == null) {
            target = "0";
        }
        return new BigDecimal(original).add(new BigDecimal(target)).toString();
    }

    public static BigDecimal divideThousand(BigDecimal quantity) {
        if (quantity == null) {
            return new BigDecimal("0.000");
        }
        return quantity.divide(decimal, 3, RoundingMode.DOWN);
    }

    public static String convertToString(BigDecimal bigDecimal) {
        if (bigDecimal == null) {
            return "0.000";
        }
        return bigDecimal.setScale(3, RoundingMode.DOWN).toString();
    }

    public static BigDecimal multiplyThousand(BigDecimal quantity) {
        if (quantity == null) {
            return new BigDecimal("0");
        }
        return quantity.multiply(decimal);
    }

    public static BigDecimal multiplyThousand(String quantity) {
        if (quantity == null) {
            return new BigDecimal("0");
        }
        return new BigDecimal(quantity).multiply(decimal);
    }

    public static BigDecimal subtractBigDecimal(BigDecimal original, BigDecimal target) {
        if (original == null) {
            original = new BigDecimal("0");
        }
        if (target == null) {
            target = new BigDecimal("0");
        }
        return original.subtract(target);
    }

    public static BigDecimal convertBigDecimal(String qty) {
        if (StringUtils.isBlank(qty)) {
            return new BigDecimal("0");
        }
        return new BigDecimal(qty);
    }

    public static void convertApplyTransferMap(Map<String, String> subBizFeaturesToUpdate, String key, Map<String, BigDecimal> map, String lineNo) {
        BigDecimal value = map.get(lineNo) == null ? new BigDecimal("0") : map.get(lineNo);
        subBizFeaturesToUpdate.put(key, value.toString());
    }

    public static boolean checkFulfillmentType(TransferOrder orderInfo) {
        return StringUtils.isBlank(orderInfo.getFulfillmentTypeCode()) || FulfillmentTypeEnum.CURRENT2CURRENT.getValue().toString().equals(orderInfo.getFulfillmentTypeCode());
    }

    public static boolean checkAllocateInType(String message) {
        if (message == null) {
            return false;
        }
        WmsOutBoundMessage wmsOutBoundMessage = JSON.parseObject(message, WmsOutBoundMessage.class);
        log.info("CalculateCommonUtil_checkAllocateInType_message:{}", JSON.toJSONString(wmsOutBoundMessage));
        if (wmsOutBoundMessage.getWmsOrderDTO() == null) {
            return false;
        }
        return ALLOCATE_IN.equals(wmsOutBoundMessage.getWmsOrderDTO().getMainOrderType());
    }

    public static void computeOutInBoundTime(List<WarehousingOrderDTO> warehousingOrderList,
                                             Map<String,String> shipTimeMap, Map<String,String> receiveTimeMap,
                                             Map<String,String> outBoundProductDateMap){
        if (CollectionUtils.isEmpty(warehousingOrderList)){
            return;
        }
        /**
         * 写入发货时间,收货时间,出库生产日期
         * 分成出库和入库
         * 找到最后一张出库 和最后一张入库
         */
        WarehousingOrderDTO shipWmsOrder = warehousingOrderList.stream()
                .filter(CalculateCommonUtil::isAllocateOut)
                .max(Comparator.comparing(WarehousingOrderDTO::getCreateTime)).orElse(null);
        WarehousingOrderDTO receiveWmsOrder = warehousingOrderList.stream()
                .filter(CalculateCommonUtil::isAllocateIn)
                .max(Comparator.comparing(WarehousingOrderDTO::getCreateTime)).orElse(null);
        //处理发货时间 和出库生产日期
        processWarehousingOrder(shipWmsOrder,shipTimeMap,outBoundProductDateMap);
        //处理收货时间
        processWarehousingOrder(receiveWmsOrder,receiveTimeMap,null);
    }
    private static void processWarehousingOrder(WarehousingOrderDTO order, Map<String, String> timeMap, Map<String, String> dateMap) {
        if (order != null) {
            Nullable.stream(order.getWmsSubOrders()).forEach(sub -> {
                String gmtCreateStr = DateFormatUtil.toString(sub.getGmtCreate(), DateFormatUtil.TIME_PATTERN);
                timeMap.put(sub.getBizSubOrderId(), gmtCreateStr);
                if (dateMap != null) {
                    String formattedDate = DateFormatUtil.formatToyyyMMdd(sub.getDom());
                    dateMap.put(sub.getBizSubOrderId(), formattedDate);
                }
            });
        }
    }

    private static boolean isAllocateOut(WarehousingOrderDTO order) {
        return ALLOCATE_OUT.equals(order.getMainOrderType()) ||
                (order.getMainOrderType() == null && Nullable.stream(order.getWmsSubOrders()).anyMatch(sub -> OUT.equals(sub.getMainOrderType())));
    }

    private static boolean isAllocateIn(WarehousingOrderDTO order) {
        return ALLOCATE_IN.equals(order.getMainOrderType()) ||
                (order.getMainOrderType() == null && Nullable.stream(order.getWmsSubOrders()).anyMatch(sub -> IN.equals(sub.getMainOrderType())));
    }

}
